home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_2.2
/
HISTRAMP
/
HISTRAMP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
6KB
|
214 lines
/*
* histramp.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/* HISTRAMP: program performs histogram modification upon a b/w image
* - yielding an image whose probability density fct is
* ramp shaped
* usage: histramp inimg outimg [-s SLOPE_SIGN] [-L]
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <tiffimage.h> /* tiff info on images */
#include <images.h> /* contains image format information */
extern void print_sos_lic ();
#define NBINS 256 /* no. of histogram bins */
#define MAX 255 /* maximum value of histogram */
#define MAXP1 256 /* no. histogram values */
#define DFLT_SLOPE 0 /* default slope of intensity histogram */
int histdistr (long *, long, long *);
int usage (short);
int input (int, char **, long *);
main (argc, argv)
int argc;
char *argv[];
{
register int i, j;
register double constant; /* a constant value */
Image *imgI; /* I/O image structures */
unsigned char **image, /* input/output data array */
transform[MAXP1]; /* transform array */
long ntotal, /* total of summation of cumulative distr. */
distr[NBINS]; /* cumulative distribution array */
long hist[NBINS], /* image histogram array */
nCol, /* image dimensions */
nRow, slopeSign; /* sign of slope (-1, 0, +1 for -, 0, +) */
double intercept, /* histogram 0-intercept */
slope; /* histogram slope */
double z;
/* read user parameter values */
if ((input (argc, argv, &slopeSign)) < 0)
return (-1);
/* invert slopeSign for white high, black low (added 13-Jul-99) */
if (slopeSign == -1)
slopeSign = 1;
else if (slopeSign == 1)
slopeSign = -1;
/* open input file */
imgI = ImageIn (argv[1]);
if (imgI->bps == 8 && imgI->spp == 3) {
printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
exit (1);
}
image = imgI->img;
nRow = ImageGetHeight (imgI);
nCol = ImageGetWidth (imgI);
printf ("image size is %dx%d\n", nCol, nRow);
/* construct histogram */
for (i = 0; i < NBINS; i++)
hist[i] = 0;
for (i = 0; i < nRow; i++)
for (j = 0; j < nCol; j++)
hist[image[i][j]]++;
/* construct cumumlative distribution */
histdistr (hist, NBINS, distr);
/* total summation under cumulative distribution omits 1/2 of lowest
* and highest occupied bins (See history note, 1 April 85) */
ntotal = distr[NBINS - 1];
/* calculate slope */
switch (slopeSign) {
case -1:
slope = -2.0 * ntotal / (double) (MAX * MAX);
break;
case 0:
slope = 0.0;
break;
case 1:
slope = 2.0 * ntotal / (double) (MAX * MAX);
break;
}
/* compute transform table for histogram equalization or histogram ramp */
switch (slopeSign) {
case -1: /* negative ramp */
intercept = ntotal / (double) MAX - slope / 2.0 * MAX;
constant = intercept / slope;
for (i = 0; i <= MAX; i++) {
z = constant * constant + 2.0 / slope * distr[i];
if (z < 0.0)
z = 0.0; /* due to quantization error */
transform[i] = (unsigned char) (-constant + 0.5 - sqrt (z));
}
break;
case 0: /* histogram equalization */
constant = ((double) MAX) / ntotal;
for (i = 0; i <= MAX; i++)
transform[i] = (unsigned char) (constant * distr[i] + 0.5);
break;
case 1: /* positive ramp */
intercept = ntotal / (double) MAX - slope / 2.0 * MAX;
constant = intercept / slope;
for (i = 0; i <= MAX; i++) {
z = constant * constant + 2.0 / slope * distr[i];
if (z < 0.0)
z = 0.0; /* due to quantization error */
transform[i] = (unsigned char) (-constant + 0.5 + sqrt (z));
}
}
/* transform each pixel value */
for (i = 0; i < nRow; i++)
for (j = 0; j < nCol; j++)
image[i][j] = transform[image[i][j]];
ImageOut (argv[2], imgI);
return (0);
}
/* USAGE: function gives instructions on usage of program
* usage: usage (flag)
* When flag is 1, the long message is given, 0 gives short.
*/
int
usage (flag)
short flag; /* flag =1 for long message; =0 for short message */
{
/* print short usage message or long */
printf ("USAGE: histramp inimg outimg [-s SLOPE_SIGN] [-L]\n");
if (flag == 0)
return (-1);
printf ("\nhistramp transforms image intensity distribution\n");
printf ("to enhance contrast in dark, medium, or light intensities.\n\n");
printf ("ARGUMENTS:\n");
printf (" inimg: input image filename (TIF)\n");
printf (" outimg: output image filename (TIF)\n\n");
printf ("OPTIONS:\n");
printf (" -s SLOPE_SIGN: is a value of -1, 0, or 1, connoting the sign\n");
printf (" of the intensity histogram shape. This increases contrast\n");
printf (" in intensity ranges high (-1), medium (0), or low (1)\n");
printf (" intensity ranges;\n");
printf (" the default SLOPE is 0, which yields uniform contrast\n");
printf (" distribution across all intensities (known as histogram\n");
printf (" equalization)\n");
printf (" -L: print Software License for this module\n");
return (-1);
}
/* INPUT: function reads input parameters
* usage: input (argc, argv, &slopeSign)
*/
#define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
input (argc, argv, slopeSign)
int argc;
char *argv[];
long *slopeSign; /* sign of slope of histogram */
{
long n;
if (argc == 1)
USAGE_EXIT (1);
if (argc == 2)
USAGE_EXIT (0);
*slopeSign = DFLT_SLOPE;
for (n = 3; n < argc; n++) {
if (strcmp (argv[n], "-s") == 0) {
if (++n == argc)
USAGE_EXIT (0);
*slopeSign = (long) atol (argv[n]);
}
else if (strcmp (argv[n], "-L") == 0) {
print_sos_lic ();
exit (0);
}
else
USAGE_EXIT (0);
}
return (0);
}